package com.mengya.completablefuture;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @ClassName CompletableFutureNetMallDemo
 * @Description 功能-->性能
 * 电商比价需求
 * 1 同一款产品，同时搜索出同款产品在各大电商的售价
 * 2 同一款产品，同时搜索出本产品在某一个电商平台下，各个入驻门店的售价是多少
 * <p>
 * 出来结果希望是同款产品在不同地方的价格清单列表，返回一个List
 * 《mysql》 in jd price is 88
 * 《mysql》 in pdd price is 98
 * 《mysql》 in taobao price is 90
 * 《mysql》 in sn price is 95
 * <p>
 * 3 要求深刻理解
 * 函数式编程
 * 链式编程
 * Stream流编程
 * @Author xiongwei.wu
 * @Date 2022/11/16 10:24
 **/
public class CompletableFutureNetMallDemo {

    static List<NetMall> list = Arrays.asList(
            new NetMall("jd"),
            new NetMall("pdd"),
            new NetMall("sn"),
            new NetMall("taobao"),
            new NetMall("dangdang"),
            new NetMall("tmall")
    );

    //同步，step by step
    public static List<String> getPriceByStep(List<NetMall> list, String productName) {
        return list.stream()
                .map(netMall -> String.format(productName + " in %s price is %.2f", netMall.getMallName(), netMall.calcPrice(productName)))
                .collect(Collectors.toList());
    }

    //异步 CompletableFuture
    public static List<String> getPriceByAsync(List<NetMall> list, String productName) {
        return list.stream()
                .map(netMall ->
                        CompletableFuture.supplyAsync(() -> {
                            return String.format(productName + " in %s price is %.2f", netMall.getMallName(), netMall.calcPrice(productName));
                        }))
                .collect(Collectors.toList())
                .stream().map(CompletableFuture::join).collect(Collectors.toList());
    }

    public static void main(String[] args) {
        long stateTime = System.currentTimeMillis();
        List<String> list = getPriceByStep(CompletableFutureNetMallDemo.list, "mysql");
        list.forEach(System.out::println);
        long endTime = System.currentTimeMillis();
        System.out.println("--同步---costTime: " + (endTime - stateTime) + "毫秒");

        System.out.println();

        long stateTime2 = System.currentTimeMillis();
        List<String> list2 = getPriceByAsync(CompletableFutureNetMallDemo.list, "mysql");
        list2.forEach(System.out::println);
        long endTime2 = System.currentTimeMillis();
        System.out.println("--异步---costTime: " + (endTime2 - stateTime2) + "毫秒");
    }

    static class NetMall {

        private String mallName;

        public NetMall(String mallName) {
            this.mallName = mallName;
        }

        public String getMallName() {
            return mallName;
        }

        public double calcPrice(String productName) {
            try {
                //检索需要1秒钟
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException exception) {
                exception.printStackTrace();
            }
            return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
        }
    }
}
